package com.qq.request;

import com.alibaba.fastjson.JSONObject;
import com.qq.response.ErrorInfo;
import com.qq.response.HttpResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

import static org.springframework.web.bind.annotation.RequestMethod.POST;

@Component
@WebFilter(filterName = "requestFilter", urlPatterns = "/*")
@Order(1)
public class HttpreiquestOverwriteFilter implements Filter {
    private static Logger logger = LoggerFactory.getLogger(HttpreiquestOverwriteFilter.class);

    private static final String jsonType = "application/json";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //校验请求的方法是否为post，contentType 是否为application/json
        if (checkRuestMethod(request)) {
            JSONObject requestJsonObject = getRequestParamJson(request);
            if (checkRequestData(requestJsonObject)) {
                Object dataJson = requestJsonObject.get("data");
                String dataStr = dataJson == null ? "" : dataJson.toString();
                ModifyBodyHttpServletRequestWrapper httpServletRequestWrapper = new ModifyBodyHttpServletRequestWrapper((HttpServletRequest) request, dataStr);
                try {
                    chain.doFilter(httpServletRequestWrapper, response);
                } catch (ServletException e) {
                    logger.error("异常", e);
                }
            } else {
                try {
                    // 如果验证失败，直接响应给前端错误信息
                    returnJson(response);
                } catch (Exception e) {
                    logger.error("授权认证过滤器异常：request=" + requestJsonObject, e);
                }
            }
        } else {
            chain.doFilter(request, response);
        }
    }

    private boolean checkRuestMethod(ServletRequest request) {
        HttpServletRequest httpReuest = (HttpServletRequest) request;
        String method = httpReuest.getMethod();
        String contentType = httpReuest.getContentType();
        return POST.name().equals(method) && jsonType.equals(contentType);
    }

    // 获取request中的body数据
    private JSONObject getRequestParamJson(ServletRequest request) {
        try (
                InputStreamReader reader = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8);
                BufferedReader streamReader = new BufferedReader(reader);
        ) {
            String inputStr = null;
            StringBuilder responseStrBuilder = new StringBuilder();
            while ((inputStr = streamReader.readLine()) != null){
                responseStrBuilder.append(inputStr);
            }
            return JSONObject.parseObject(responseStrBuilder.toString());

        } catch (Throwable e) {
            logger.error("参数转化异常:", e);
            e.printStackTrace();
        }
        return null;
    }

    // 检查请求数据并对sign验证
    private boolean checkRequestData(JSONObject requestJsonObject) {
        // TODO 自己实现
        return true;
    }

    private void returnJson(ServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try (
                PrintWriter writer = response.getWriter();
        ) {
            ErrorInfo errorInfo = ErrorInfo.builder()
                    .errorCode("400")
                    .errorMessage("token valid fail")
                    .build();
            HttpResult result = HttpResult.builder()
                    .sucess(false)
                    .errorInfo(errorInfo)
                    .build();
            writer.print(JSONObject.toJSONString(result));
        } catch (Throwable e) {
            logger.error("response error", e);
        }
    }

    @Override
    public void destroy() {
    }


}
